package com.fingard.dsp.bank.directbank.hsbc01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpReceiver;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.ForeignBankUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author XueJy on 2018/9/12.
 * @version 1.0
 */
public class HSBC01BatPayRec extends HSBC01Base implements IBatPayRec {


    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        //保险
        if ("0".equals(this.getBankConfig().getValueAsString("channelFalg"))) {
            //支付请求码
            retAts.reqSeqID = p_req1988.reqBatchNO;
            //指令代码
            StringBuilder tmpMsg = new StringBuilder();
            String batchNo = p_req1988.reqBatchNO;
            int maxBatch = 0;
            File dataFileDir = new File(StringHelper.trimEnd(getCommonDataFileDirectory(new Date(), "HSHBC"), File.separator) + File.separator + "batchPay");
            if (dataFileDir.exists()) {
                int len = dataFileDir.listFiles().length;
                if (len > 0) {
                    maxBatch = len + 1;
                } else {
                    maxBatch = 1;
                }
            } else {
                maxBatch = 1;
            }
            //今日批数
            p_req1988.smsCode = String.valueOf(maxBatch - 1);
            writePayCommonHeader(tmpMsg, p_req1988);
            writePayBodyParams(tmpMsg, p_req1988);
            String fileName = "DCA_HO07_" + Format.Date8Format.format(new Date()) + String.format("%2s", maxBatch).replace(" ", "0") + ".txt";
            FileHelper.writeFile(dataFileDir + File.separator + batchNo + ".txt", fileName, getCharset());
            String sendFilePath = dataFileDir + File.separator + fileName;
            WriteBankLogStep2(tmpMsg.toString());
            FileHelper.writeFile(sendFilePath, tmpMsg.toString(), "UTF-8");
            FtpReceiver ftpReceiver = sendToBank(sendFilePath, fileName, EnumTransMode.BatchPayForHF.getValue());
            retAts.respCode = "0";
            retAts.reqSeqID = batchNo;
            if (ftpReceiver.isCompleted) {
                retAts.respInfo = "支付文件上传成功";
                retAts.transState = "Uploaded";
                retAts.payInfoCode = "Uploaded";
            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                retAts.respInfo = "支付文件上传失败";
                retAts.transState = "BatchFailed";
                retAts.payInfoCode = "BatchFailed";
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = ftpReceiver.connMsg;
            }
        } else {
            //拼接付款请求报文
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter);
            writeFileContentCNBatch(xmlWriter, p_req1988);
            //生成付款文件目录
            String payDate = DateHelper.convertD10toD8(p_req1988.payDate);
            String payFilePath = getBankConfig().getValueAsString("PayFilePath") + File.separator + payDate + File.separator
                    + "CN" + payDate.substring(2, 8) + "_" + "PP" + "_v3_" + p_req1988.reqBatchNO + ".txt";
            WriteBankLogLn("请求银行的报文：" + xmlWriter.toXmlString());
            foreignBankHelper = new ForeignBankUtil(getBankConfig(), bankFront, getSbLog(), getCharset());
            //生成付款文件并上传
            String[] bankResult = new String[]{"", ""};
            if (StringHelper.hasAnyChar(getBankConfig().getValueAsString("transType"))
                    && getBankConfig().getValueAsString("transType").equals("true")) {
                //付款文件需要加密加签
                bankResult = foreignBankHelper.uploadPayFileIsEncrypt(xmlWriter.toXmlString(), payFilePath, getCharset(), "sftpserverHK");
            } else {
                //付款文件不需要加密
                bankResult = foreignBankHelper.uploadPayFile(xmlWriter.toXmlString(), payFilePath, getCharset(), "sftpserverHK");
            }
            //响应到ats
            retAts.reqSeqID = p_req1988.reqBatchNO;
            retAts.respCode = "0";
            retAts.respInfo = bankResult[1];
            retAts.transState = bankResult[0];
            retAts.payInfoCode = retAts.transState;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        //保险
        if ("0".equals(this.getBankConfig().getValueAsString("channelFalg"))) {
            //下载结果文件
            downloadFile();
//        String payack = getReceivePath("payack", p_req1998.getBgnDateTime());
            String payack = getReceivePath(EnumDirType.PayAck.getValue(), p_req1998.getBgnDateTime());
            List<String> filenames = getDirectoryAllFileName(payack);
            String batchNo = p_req1998.reqBatchNO;
            boolean isAck = false;
            boolean refusedFlag = false;
            String refusedMessage = "";
            for (String filename : filenames) {
                if (!filename.contains(batchNo)) {
                    continue;
                }
                String contain = "";
                synchronized (this) {
                    //读取文件内容
                    contain = FileHelper.readFileText(payack + File.separator + filename, getCharset());
                }
                WriteBankLogLn("回盘ACK文件内容:\n" + contain);
                String[] ackres = contain.split("\n");
                String[] ackhead = ackres[0].split(",");
                if (ackhead.length > 16 && ackhead[2].trim().equals(batchNo)) {
                    if ("RECEIVED BY BANK".equals(ackhead[16].trim())) {
                        isAck = true;
                        break;
                    } else {
                        refusedFlag = true;
                        refusedMessage = ackhead[16].trim();
                    }
                }
            }
            if (isAck) {
                boolean isResult = false;
                String payreport = getReceivePath(EnumDirType.PayReport.getValue(), p_req1998.getBgnDateTime());
//            String payreport = getReceivePath("payreport", p_req1998.getBgnDateTime());
                filenames = getDirectoryAllFileName(payreport);
                for (String filename : filenames) {
                    String contain = "";
                    synchronized (this) {
                        //读取文件内容
                        contain = FileHelper.readFileText(payreport + File.separator + filename, getCharset());
                    }
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(contain, tmpSbMsg);
                    //ACH 结果文件
                    if (tmpBkReader != null) {
                        //批次号是否对上
                        if (tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlPmtInfAndSts/OrgnlPmtInfId").equals(batchNo)) {
                            retAts.respCode = "0";
                            retAts.reqSeqID = batchNo;
                            WriteBankLogLn("批量付款结果文件返回内容:+\n" + contain);
                            while (tmpBkReader.read("/Document/CstmrPmtStsRpt/OrgnlPmtInfAndSts/TxInfAndSts")) {
                                RetAtsBatPayRecDetail tmpDetail = new RetAtsBatPayRecDetail();
                                //ACSC- Processed and sent to beneficiary bank
                                //PDNG- Unprocessed
                                //RJCT- Rejected
                                tmpDetail.result = tmpBkReader.readedXElement.getSingleText("TxSts");
                                //Processed Payments
                                tmpDetail.payAct = p_req1998.ownAct;
                                tmpDetail.payInfoCode = tmpDetail.result + "+" + tmpBkReader.readedXElement.getSingleChild("StsRsnInf").getSingleText("AddtlInf");
                                tmpDetail.postScript = tmpBkReader.readedXElement.getSingleText("OrgnlInstrId");
                                tmpDetail.recName = tmpBkReader.readedXElement.getSingleChild("OrgnlTxRef").getSingleChild("Cdtr").getSingleText("Nm");
                                tmpDetail.recAct = tmpBkReader.readedXElement.getSingleChild("OrgnlTxRef").getSingleChild("CdtrAcct").getSingleChild("Id").getSingleChild("Othr").getSingleText("Id");
                                tmpDetail.payAmount = tmpBkReader.readedXElement.getSingleChild("OrgnlTxRef").getSingleChild("Amt").getSingleText("InstdAmt");
                                retAts.writeRetDetail(tmpDetail);
                            }
                            isResult = true;
                            break;
                        }
                    }
                }
                if (!isResult) {
                    retAts.respCode = "0";
                    retAts.respInfo = "银行还未返回结果文件";
                    retAts.transState = "I4101";
                    retAts.payInfoCode = "I4101";
                }
            } else if (refusedFlag) {
                retAts.respCode = "0";
                retAts.respInfo = refusedMessage;
                retAts.transState = "BatchFailed";
                retAts.payInfoCode = refusedMessage;
            } else {
                String bakUpPath = getCommonDataFileDirectory(p_req1998.getBgnDateTime(), "HSHBC") + File.separator + "batchPay";
                //如果查询没有记录则原文件再次发起查询
                String fileNameMap = batchNo + ".txt";
                String fileName = FileHelper.readFileText(bakUpPath + File.separator + fileNameMap, getCharset());
                String sendFilePath = bakUpPath + File.separator + fileName;
                FtpReceiver ftpReceiver = sendToBank(sendFilePath, fileName, EnumTransMode.BatchPayForHF.getValue());
                if (ftpReceiver.isCompleted) {
                    retAts.respCode = "0";
                    retAts.respInfo = "未查询到ACK文件,再次发起支付,文件上传成功";
                    retAts.transState = "Uploaded";
                    retAts.payInfoCode = "Uploaded";
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = ftpReceiver.connMsg;
                }
            }
        } else {
            String respCode = "";
            String respInfo = "";
            //处理ack文件或者MT文件，获取支付状态  result={"付款状态码","响应信息"}
            foreignBankHelper = new ForeignBankUtil(getBankConfig(), bankFront, getSbLog(), getCharset());
            String[] result = foreignBankHelper.getPayStatus(p_req1998.reqBatchNO, p_req1998.getBgnDateTime());
            if (result.length == 2 && StringHelper.hasAnyChar(result[0])) {
                if ("A90".equals(result[0])) {
                    retAts.respCode = "0";
                    retAts.respInfo = result[1];
                    retAts.reqSeqID = p_req1998.reqBatchNO;
                    retAts.transState = result[0];
                    retAts.payInfoCode = retAts.transState;
                    retAts.writeBeforeDetail();
                } else {
                    retAts.respCode = "0";
                    retAts.respInfo = result[1];
                    retAts.reqSeqID = p_req1998.reqBatchNO;
                    retAts.writeBeforeDetail();
                    String batchIdPath = StringHelper.trimEndFileSp(getBankConfig().getValueAsString("DealedPath"))
                            + File.separator + DateHelper.convertD10toD8(p_req1998.bgnDate) + File.separator + "batch.txt";
                    String batchIdCont = FileHelper.readFileText(batchIdPath, getCharset());
                    if (StringHelper.hasAnyChar(batchIdCont)) {
                        String[] batchIdArr = batchIdCont.split("###");
                        for (String bString : batchIdArr) {
                            String[] bStringArr = bString.split("@");
                            if (bStringArr[0].equals(p_req1998.reqBatchNO)) {
                                for (int i = 1; i < bStringArr.length; i++) {
                                    String[] result2 = foreignBankHelper.getPayStatus(bStringArr[i], p_req1998.getBgnDateTime());
                                    if (result2.length == 2 && StringHelper.hasAnyChar(result2[0])) {
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        tmpRetDetail.payAct = p_req1998.ownAct;
                                        tmpRetDetail.payName = "";
                                        tmpRetDetail.recAct = "";//收款人号
                                        tmpRetDetail.recName = "";//收款人名
                                        tmpRetDetail.postScript = bStringArr[i];//批内流水号
                                        tmpRetDetail.payAmount = "";//金额
                                        tmpRetDetail.memo = "";//备注
                                        tmpRetDetail.result = result[0];//COMPLETE–成功、FAIL-失败
                                        tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                        retAts.writeRetDetail(tmpRetDetail);
                                    } else {
                                        respCode = "-1";
                                        respInfo = "查询状态异常";
                                    }
                                }
                            }
                        }
                    } else {
                        retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
                        retAts.respCode = "0";
                        retAts.respInfo = result[1];
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState = result[0];
                        retAts.payInfoCode = retAts.transState;
                        retAts.writeBeforeDetail();
                    }
                    if (StringHelper.isNullOrEmpty(retAts.transState)) {
                        retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
                        retAts.respCode = "0";
                        retAts.respInfo = result[1];
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState = result[0];
                        retAts.payInfoCode = retAts.transState;
                        retAts.writeBeforeDetail();
                    }
                }
            } else {
                respCode = "-1";
                respInfo = "查询状态异常";
            }
            if ("-1".equals(respCode)) {
                retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
                retAts.respCode = "-1";
                retAts.respInfo = respInfo;
                retAts.reqSeqID = p_req1998.reqBatchNO;
                retAts.writeBeforeDetail();
            }
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        //008.001.02
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req9188.reqHeader);

        String batchNo = p_req9188.reqBatchNO;
        //指令代码
        XmlTextWriter xmlWriterMsg = new XmlTextWriter();
        String bakUpPath = getCommonDataFileDirectory(new Date(), "HSHBC");
        int maxBatch = 0;
        File dataFileDir = new File(StringHelper.trimEnd(bakUpPath, File.separator) + File.separator + "batchRec");
        if (dataFileDir.exists()) {
            int len = dataFileDir.listFiles().length;
            if (len > 0) {
                maxBatch = len + 1;
            } else {
                maxBatch = 1;
            }
        } else {
            maxBatch = 1;
        }

        p_req9188.smsCode = String.valueOf(maxBatch);
        writeRecCommonHeader(xmlWriterMsg, p_req9188);
        writeRecBodyParams(xmlWriterMsg, p_req9188);
        writeEnds(xmlWriterMsg);
        //首期14
        String isFirst;
        if ("918801".equals(p_req9188.reqHeader.commandCode)) {
            isFirst = "14";
        } else {
            isFirst = "15";
        }
        //加入首续期标志
        String fileName = "L" + isFirst + "50100000" + Format.Date8Format.format(new Date()) + String.format("%2s", maxBatch).replace(" ", "0") + ".xml";
        String sendFilePath = getCommonDataFileDirectory(new Date(), "HSHBC") + File.separator + "batchRec" + File.separator + fileName;
        FileHelper.writeFile(dataFileDir + File.separator + batchNo + ".txt", fileName, getCharset());
        WriteBankLogStep2(xmlWriterMsg.toXmlString());
        FileHelper.writeFile(sendFilePath, xmlWriterMsg.toXmlString(), getCharset());
        FtpReceiver ftpReceiver = sendToBanks(sendFilePath, fileName, EnumTransMode.BatchRecForHF.getValue());
        retAts.respCode = "0";
        retAts.reqSeqID = batchNo;
        if (ftpReceiver.isCompleted) {
            retAts.respInfo = "支付文件上传成功";
            retAts.transState = "Uploaded";
            retAts.payInfoCode = "Uploaded";
        } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
            retAts.respInfo = "支付文件上传失败";
            retAts.transState = "BatchFailed";
            retAts.payInfoCode = "BatchFailed";
        } else {
            retAts.respCode = "-1";
            retAts.respInfo = ftpReceiver.connMsg;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req9198.reqHeader);
        //下载结果文件
        downloadFile();
        //查看ack文件
        String ackPath = getReceivePath(EnumDirType.RecAck.getValue(), p_req9198.getBgnDateTime());
//        String ackPath = getReceivePath("recack",p_req9198.getBgnDateTime());
        List<String> filenames = getDirectoryAllFileName(ackPath);
        String batchNo = p_req9198.reqBatchNO;
        List<RetAtsBatPayRecDetail> retAtsDetails = new ArrayList<RetAtsBatPayRecDetail>();
        //是否有ack文件
        boolean ackFlag = false;
        //是否被拒绝了
        boolean refusedFlag = false;
        //是否有结果
        boolean hasResult = false;
        String refusedMessage = "";
        for (String filename : filenames) {
            String contain = "";
            synchronized (this) {
                //读取文件内容
                contain = FileHelper.readFileText(ackPath + File.separator + filename, "UTF-8");
            }
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(contain, tmpSbMsg);
            //ack解析
            if (tmpBkReader != null) {
                String orgnlMsgId = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/OrgnlMsgId");
                if (orgnlMsgId.equals(batchNo)) {
                    WriteBankLogLn("批量收款ACK文件内容:+\n" + contain);
                    ackFlag = true;
                    retAts.respCode = "0";
                    String grpSts = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/GrpSts");
                    if ("ACCP".equals(grpSts)) {
                        String reportPath = getReceivePath(EnumDirType.RecReport.getValue(), p_req9198.getBgnDateTime());
//                      String reportPath = getReceivePath("recreport", p_req9198.getBgnDateTime());
//
                        if (new File(reportPath).exists()) {
                            filenames = getDirectoryAllFileName(reportPath);
                            for (String reportFilename : filenames) {
                                //088-251418-011(20180903-1)
                                if (!reportFilename.substring(0, reportFilename.indexOf("(")).replace("-", "").equals(p_req9198.ownAct.replace(" ", ""))) {
                                    continue;
                                }
                                InputStream inputStream = null;
                                InputStreamReader isr = null;
                                BufferedReader reader = null;
                                try {
                                    inputStream = new FileInputStream(reportPath + File.separator + reportFilename);
                                    isr = new InputStreamReader(inputStream, "GBK");
                                    reader = new BufferedReader(isr);
                                    String sLine;
                                    //读取文件内容
                                    while ((sLine = reader.readLine()) != null) {
                                        if (sLine.startsWith("Batch Reference ID")) {
                                            continue;
                                        }
                                        WriteBankLogLn(sLine);
                                        String[] results = sLine.split(",");
                                        if (results.length > 10) {
                                            if (results[0].equals(batchNo)) {
                                                RetAtsBatPayRecDetail detail = new RetAtsBatPayRecDetail();
                                                detail.payAct = results[1].trim();
                                                detail.payName = results[2].trim();
                                                //保�尉��
                                                detail.usage = results[3].trim();
                                                detail.curType = convertCurToATS(results[4].trim());
                                                detail.payAmount = results[5].trim();
                                                detail.result = results[6].trim();
                                                detail.payInfoCode = detail.result;
                                                detail.memo = detail.payInfoCode;
                                                String errorCode = results[7].trim();
                                                String errorMsg = results[8].trim();

                                                if (!"".equals(errorCode) && !"".equals(errorMsg)) {
                                                    detail.payInfoCode = detail.payInfoCode + "+" + errorCode + "+" + errorMsg;
                                                    detail.memo = errorMsg;
                                                }

                                                detail.postScript = results[10];
                                                retAtsDetails.add(detail);
                                            } else {
                                                break;
                                            }
                                        }
                                    }
                                    if (retAtsDetails.size() > 0) {
                                        break;
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {
                                    if (inputStream != null) {
                                        inputStream.close();
                                    }
                                    if (reader != null) {
                                        reader.close();
                                    }
                                    if (isr != null) {
                                        isr.close();
                                    }
                                }
                            }
                        }
                    } else {
                        //拒绝 支付失败  可能存在重复支付后再次发起的拒绝. 要看完所有ACK 若有 则Accep  则成功
                        refusedFlag = true;
                        refusedMessage = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/StsRsnInf/AddtlInf");
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpSbMsg.toString();
                retAts.writeAfterDetail();
                return retAts;
            }
        }
        retAts.respCode = "0";
        //如果有detail则有支付结果
        if (retAtsDetails.size() > 0) {
            for (RetAtsBatPayRecDetail detail : retAtsDetails) {
                retAts.writeRetDetail(detail);
            }
            //如果没找到ack则重新发起支付
        } else if (!ackFlag) {
            retAts.respCode = "-1";
            retAts.respInfo = "暂时无法查询到ACK文件,请稍后再试";
            return retAts;
        } else if (refusedFlag) {
            retAts.respInfo = refusedMessage;
            retAts.transState = "BatchFailed";
            retAts.payInfoCode = refusedMessage;
        } else {
            retAts.respInfo = "银行还未返回结果文件";
            retAts.transState = "I4101";
            retAts.payInfoCode = "I4101";
        }
        retAts.writeAfterDetail();
        return retAts;
    }

}
